/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//		File Name		:		CEmitter.h
//
//		Author			:		Kevin Jordan
//
//		Purpose			:		A header for all functions and members of the EMitter class
//
//		Dates			:		Written( Feb 24, 2011 ) by Kevin Jordan		LastUpdate( Feb 24, 2011  ) by Kevin Jordan 
//	
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "CEmitter.h"
#include "SGD Wrappers/CSGD_TextureManager.h"
#include "SGD Wrappers/CSGD_Direct3D.h"
#include "MathLib.h"
#include <ctime>


CEmitter::CEmitter()
{
	m_nMaxNumOfParticles = 0;
	m_fPosX = 0;
	m_fPosY = 0;
	m_fVelX = 0;
	m_fVelY = 0;
	m_fSpread = 0.0f;
	RandomOffsetX = 0;
	RandomOffsetY = 0;
}

CEmitter::~CEmitter()
{
	for( unsigned int i = 0; i < vParticles.size(); i++ )
	{
		delete vParticles[i];
		vParticles.erase(vParticles.begin() + i);
	}
}

void CEmitter::Render()
{
	CSGD_TextureManager* pTM = CSGD_TextureManager::GetInstance();
	//CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState();

	for( unsigned int i = 0; i < vParticles.size(); i++ )
	{
		pTM->Draw( vParticles[i]->GetImageID(), (int)vParticles[i]->GetPosX()/2, (int)vParticles[i]->GetPosY()/2,
			vParticles[i]->GetCurScale(), vParticles[i]->GetCurScale(), 0, pTM->GetTextureWidth(vParticles[i]->GetImageID()) * vParticles[i]->GetCurScale()/2,
			pTM->GetTextureHeight(vParticles[i]->GetImageID()) * vParticles[i]->GetCurScale()/2, vParticles[i]->GetRotation(), vParticles[i]->GetCurColor());
	}
}

/*
<algorithm.h>

OM.cpp;

Sort(v.begin(), v.End(), zsort)
bool zsort (point a, point b)
{
return 
}

om::render();
*/

void CEmitter::Update(float fElapsedTime)
{
	while( vParticles.size() < (unsigned int)m_nMaxNumOfParticles )
	{
		CreateParticle();
	}

	for( unsigned int i =0; i < vParticles.size(); i++ )
	{
		if(vParticles[i]->GetAcelX() > 0)
			vParticles[i]->SetVelX(vParticles[i]->GetVelX() +  rand()%((int)absolute(vParticles[i]->GetAcelX())) * fElapsedTime);
		
		if(vParticles[i]->GetAcelX() < 0)
			vParticles[i]->SetVelX(vParticles[i]->GetVelX() -  rand()%((int)absolute(vParticles[i]->GetAcelX())) * fElapsedTime);
		
		if(vParticles[i]->GetAcelY() > 0)
			vParticles[i]->SetVelY(vParticles[i]->GetVelY() +  rand()%((int)absolute(vParticles[i]->GetAcelY())) * fElapsedTime);
		
		if(vParticles[i]->GetAcelY() < 0)
			vParticles[i]->SetVelY(vParticles[i]->GetVelY() -  rand()%((int)absolute(vParticles[i]->GetAcelY())) * fElapsedTime);

		vParticles[i]->SetPosX( (float)vParticles[i]->GetPosX() + (float)((float)(rand()% (int)vParticles[i]->GetVelX())* fElapsedTime));//  * fElapsedTime);
		vParticles[i]->SetPosY( (float)vParticles[i]->GetPosY() + (float)((float)(rand()% (int)vParticles[i]->GetVelY())* fElapsedTime));//  * fElapsedTime);	

		vParticles[i]->Update(fElapsedTime);

		vParticles[i]->SetLife((vParticles[i]->GetLife() - fElapsedTime));
		if( vParticles[i]->GetLife() < 0 )
		{
			delete vParticles[i];
			vParticles.erase(vParticles.begin() + i);
			//--i;
		}
	}
}


void CEmitter::CreateParticle()
{	
	if(BaseParticle.GetLife() != 0)
		BaseParticle.SetLife((float)(rand()% (int)BaseParticle.GetLife()));
	if(GetOffSetX() == 0 && GetOffSetY() != 0)
	{
		CParticle* TempParticle = new CParticle( GetPosX(), (GetPosY() + (rand()%((int)GetOffSetY() * 2) - GetOffSetY()) ), BaseParticle.GetVelX(), BaseParticle.GetVelY(), BaseParticle.GetAcelX(), BaseParticle.GetAcelY(), 
			BaseParticle.GetStartColor(),BaseParticle.GetEndColor(), BaseParticle.GetStartScale(), BaseParticle.GetEndScale(), BaseParticle.GetRotation(), BaseParticle.GetImageID(),  (int)BaseParticle.GetLife());
		vParticles.push_back(TempParticle);
	}
	else if(GetOffSetX() != 0 && GetOffSetY() == 0)
	{
		CParticle* TempParticle = new CParticle( (GetPosX() + (rand()%((int)GetOffSetX() * 2) - GetOffSetX()) ), (GetPosY() + (rand()%((int)GetOffSetY() * 2) - GetOffSetY()) ), BaseParticle.GetVelX(), BaseParticle.GetVelY(), BaseParticle.GetAcelX(), BaseParticle.GetAcelY(), 
			BaseParticle.GetStartColor(),BaseParticle.GetEndColor(), BaseParticle.GetStartScale(), BaseParticle.GetEndScale(), BaseParticle.GetRotation(), BaseParticle.GetImageID(),  (int)BaseParticle.GetLife());
		vParticles.push_back(TempParticle);
	}
	else if(GetOffSetX() == 0 && GetOffSetY() == 0)
	{
		CParticle* TempParticle = new CParticle( GetPosX(), GetPosY(), BaseParticle.GetVelX(), BaseParticle.GetVelY(), BaseParticle.GetAcelX(), BaseParticle.GetAcelY(), 
			BaseParticle.GetStartColor(),BaseParticle.GetEndColor(), BaseParticle.GetStartScale(), BaseParticle.GetEndScale(), BaseParticle.GetRotation(), BaseParticle.GetImageID(),  (int)BaseParticle.GetLife());
		vParticles.push_back(TempParticle);
	}
	else if(GetOffSetX() != 0 && GetOffSetY() != 0)
	{
		CParticle* TempParticle = new CParticle( (GetPosX() + (rand()%((int)GetOffSetX() * 2) - GetOffSetX()) ), (GetPosY() + (rand()%((int)GetOffSetY() * 2) - GetOffSetY()) ), BaseParticle.GetVelX(), BaseParticle.GetVelY(), BaseParticle.GetAcelX(), BaseParticle.GetAcelY(), 
			BaseParticle.GetStartColor(),BaseParticle.GetEndColor(), BaseParticle.GetStartScale(), BaseParticle.GetEndScale(), BaseParticle.GetRotation(), BaseParticle.GetImageID(),  (int)BaseParticle.GetLife());
		vParticles.push_back(TempParticle);
	}
}


bool CEmitter::Load(const char* EmitterLoc )
{
	srand(unsigned int(time(0)));
	///////////////////////////////////////////////////////////////////
	//Set the MaxNumber of Particles as well as the Particle Details///
	///////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////

	TiXmlDocument doc;

	if(doc.LoadFile(EmitterLoc) == false)
		return false;

	TiXmlElement* Root = doc.RootElement();
	if(Root == NULL)
		return false;

	TiXmlElement* xNumParticles = Root->FirstChildElement("xNumParticles");
	m_nMaxNumOfParticles = atoi(xNumParticles->GetText());

	TiXmlElement* xRandom = Root->FirstChildElement("xRandom");
	if(xRandom)
	{
		TiXmlElement* xRandomX = xRandom->FirstChildElement("xRandomX");
		SetOffSetX((float)atoi(xRandomX->GetText()));

		TiXmlElement* xRandomY = xRandom->FirstChildElement("xRandomX");
		SetOffSetY((float)atoi(xRandomY->GetText()));
	}

	TiXmlElement* xSpread = Root->FirstChildElement("xSpread");
	SetSpread((float)atof(xSpread->GetText()));


	TiXmlElement* xVelocity = Root->FirstChildElement("xVelocity");
	if(xVelocity)
	{
		TiXmlElement* xVelFX = xVelocity->FirstChildElement("xVelFX");
		SetVelX((float)atof(xVelFX->GetText()));

		TiXmlElement* xVelFY = xVelocity->FirstChildElement("xVelFY");
		SetVelY((float)atof(xVelFY->GetText()));
	}

	TiXmlElement* xParticle = Root->FirstChildElement("xParticle");
	if(xParticle)
	{
		TiXmlElement* xParticleAcceleration = xParticle->FirstChildElement("xParticleAcceleration");
		if(xParticleAcceleration)
		{
			TiXmlElement* xParAccelFX = xParticleAcceleration->FirstChildElement("xParAccelFX");
			BaseParticle.SetAcelX((float)atof(xParAccelFX->GetText()));

			TiXmlElement* xParAccelFY = xParticleAcceleration->FirstChildElement("xParAccelFY");
			BaseParticle.SetAcelY((float)atof(xParAccelFY->GetText()));
		}

		TiXmlElement* xParticleVelocity = xParticle->FirstChildElement("xParticleVelocity");
		if(xVelocity)
		{
			TiXmlElement* xParVelFX = xParticleVelocity->FirstChildElement("xParVelFY");
			BaseParticle.SetVelX((float)atof(xParVelFX->GetText()));

			TiXmlElement* xParVelFY = xParticleVelocity->FirstChildElement("xParVelFY");
			BaseParticle.SetVelY((float)atof(xParVelFY->GetText()));
		}

		TiXmlElement* xParticleLife = xParticle->FirstChildElement("xParticleLife");
		BaseParticle.SetLife((float)atof(xParticleLife->GetText()));

		TiXmlElement* xParticleStartScale = xParticle->FirstChildElement("xParticleStartScale");
		BaseParticle.SetStartScale((float)atof(xParticleStartScale->GetText()));
		BaseParticle.SetCurScale(BaseParticle.GetStartScale());

		TiXmlElement* xParticleEndScale = xParticle->FirstChildElement("xParticleEndScale");
		BaseParticle.SetEndScale((float)atof(xParticleEndScale->GetText()));

		TiXmlElement* xParticleRotation = xParticle->FirstChildElement("xParticleRotation");
		BaseParticle.SetRotation((float)atof(xParticleRotation->GetText()));

		TiXmlElement* xFilename = xParticle->FirstChildElement("xFilename");
		BaseParticle.SetFilename(xFilename->GetText());
		BaseParticle.SetImageID(CSGD_TextureManager::GetInstance()->LoadTexture(BaseParticle.GetFilename()));

		int tempA, tempR, tempG, tempB;
		TiXmlElement* xParticleStartColor = xParticle->FirstChildElement("xParticleStartColor");
	//	BaseParticle.SetStartColor((float)atof(xParticleStartColor->GetText()));
		if(xParticleStartColor)
		{
			TiXmlElement* xParticleStartColorA = xParticleStartColor->FirstChildElement("xParticleStartColorA");
			tempA = atoi(xParticleStartColorA->GetText());

			TiXmlElement* xParticleStartColorR = xParticleStartColor->FirstChildElement("xParticleStartColorR");
			tempR = atoi(xParticleStartColorR->GetText());

			TiXmlElement* xParticleStartColorG = xParticleStartColor->FirstChildElement("xParticleStartColorG");
			tempG = atoi(xParticleStartColorG->GetText());

			TiXmlElement* xParticleStartColorB = xParticleStartColor->FirstChildElement("xParticleStartColorB");
			tempB = atoi(xParticleStartColorB->GetText());

			BaseParticle.SetStartColor(D3DCOLOR_ARGB(tempA,tempR,tempG, tempB));
		}

		TiXmlElement* xParticleEndColor = xParticle->FirstChildElement("xParticleEndColor");
		//BaseParticle.SetEndColor((float)atof(xParticleEndColor->GetText()));
		if(xParticleEndColor)
		{
			TiXmlElement* xParticleEndColorA = xParticleEndColor->FirstChildElement("xParticleEndColorA");
			tempA = atoi(xParticleEndColorA->GetText());

			TiXmlElement* xParticleEndColorR = xParticleEndColor->FirstChildElement("xParticleEndColorR");
			tempR = atoi(xParticleEndColorR->GetText());

			TiXmlElement* xParticleEndColorG = xParticleEndColor->FirstChildElement("xParticleEndColorG");
			tempG = atoi(xParticleEndColorG->GetText());

			TiXmlElement* xParticleEndColorB = xParticleEndColor->FirstChildElement("xParticleEndColorB");
			tempB = atoi(xParticleEndColorB->GetText());

			BaseParticle.SetEndColor(D3DCOLOR_ARGB(tempA,tempR,tempG, tempB));
		}
	}

	//     XElement xSourceBlend = xRoot.Element("xSourceBlend");
	//     if(xSourceBlend != null)
	//     {
	//         SourceBlendComboBox.Text = xSourceBlend.Value;
	//     }

	//     XElement xDestBlend = xRoot.Element("xDestBlend");
	//     if (xDestBlend != null)
	//     {
	//         DestinationBlendComboBox.Text = xDestBlend.Value;
	//     }
	return true;
}